﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Cashier.utils;
using System.IO;

namespace Cashier.data
{
    public partial class DataRecoveryForm : Form
    {
        private long totalSize; //文件长度
        private long position; //当前读取位置
        private byte[] buffer; //读入文件
        private int buffer_size = 4096; //每次读取字节的长度
        private FileStream fsReader; //文件流读取类
        private delegate void UpdateUI(long position); //更新UI
        private String recoveryPath; //文件恢复路径

        public DataRecoveryForm()
        {
            InitializeComponent();
        }

        #region 控件事件

        /// <summary>
        /// 选择文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_selectfile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.DefaultExt = ".bk";
                openFileDialog.Filter = "数据文件(*.bk)|*.bk";
                DialogResult result = openFileDialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    String path = openFileDialog.FileName;
                    textBox_path.Text = path;
                }
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 开始恢复
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_recovery_Click(object sender, EventArgs e)
        {
            try
            {
                String path = textBox_path.Text.Trim();
                FileInfo file = new FileInfo(path);
                if (file.Exists)
                {
                    button_recovery.Enabled = false;
                    recoveryPath = System.Windows.Forms.Application.StartupPath + @"\db\cashier.s3db";
                    file = new FileInfo(recoveryPath);
                    if (file.Exists)
                        file.Delete();
                    this.ReadFile(path);
                }
                else
                    MessageBox.Show("数据文件不存在！");
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        #endregion

        #region 功能方法实现

        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="path"></param>
        private void ReadFile(String path)
        {
            try
            {
                fsReader = new FileStream(path, FileMode.Open);
                totalSize = fsReader.Length;

                //设置进度条最大值和最小值
                progressBar1.Minimum = 0;
                progressBar1.Maximum = (int)totalSize;

                if (totalSize > buffer_size)
                {
                    buffer = new byte[buffer_size];
                }
                else
                {
                    buffer = new byte[(int)totalSize];
                }
                fsReader.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(AsyncCopyFile), null);
            }
            catch (Exception ex)
            {
                button_recovery.Enabled = true;
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 异步复制文件
        /// </summary>
        /// <param name="ar"></param>
        private void AsyncCopyFile(IAsyncResult ar)
        {
            try
            {
                int readlenth = 0;
                lock (fsReader)
                {
                    readlenth = fsReader.EndRead(ar);
                }

                FileStream fsWriter = new FileStream(recoveryPath, FileMode.Append, FileAccess.Write);
                fsWriter.Write(buffer, 0, buffer.Length);
                fsWriter.Close();

                position += readlenth;
                BeginInvoke(new UpdateUI(SyncUpdateProcessBar), new object[] { position });

                if (position >= totalSize)
                {
                    fsReader.Close();
                    return;
                }

                lock (fsReader)
                {
                    int leftSize = (int)(totalSize - position);
                    if (leftSize < buffer_size)
                    {
                        buffer = new byte[leftSize];
                    }
                    fsReader.BeginRead(buffer, 0, buffer.Length, AsyncCopyFile, null);
                }
            }
            catch (Exception ex)
            {
                button_recovery.Enabled = true;
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 更新进度条
        /// </summary>
        /// <param name="position"></param>
        private void SyncUpdateProcessBar(long position)
        {
            progressBar1.Value = (int)position;
            if (position >= totalSize)
            {
                if (fsReader != null)
                {
                    fsReader.Close();
                    fsReader = null;
                }
                button_recovery.Enabled = true;
                MessageBox.Show("恢复完毕！");
                this.Close();
            }
        }

        #endregion
    }
}
